package com.web.uploader.controller;

import java.io.File;



import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import com.web.uploader.common.utils.FileUploadUtil;
import com.web.uploader.controller.dto.BaseResDto;
import com.web.uploader.controller.dto.ChunksReqDto;
import com.web.uploader.entity.FileInfo;
import com.web.uploader.service.IFileInfoService;

@Controller
@RequestMapping(value="/file")
public class FileInfoController extends BaseControler{

	@Autowired
	private  IFileInfoService fileInfoService; 
	
	private String uploadUrl = "/upload";
	
	private String whitelist = "gif.jpg.jpeg.bmp.png.mp3.mp4.exe.txt.avi.flv.doc.docx.ppt.pptx.xls.xlsx,GIF.JPG.JPEG.BMP.PNG.MP3.MP4.EXE.TXT.AVI.FLV.DOC.DOCX."
			+ "PPT.PPTX.XLS.XLSX,zip"
			+ ",ZIP,RAR,rar";
	/**
	 * 
	 * <p>Title: uploadFile</p>
	 * <p>Description:普通上传文件 </p>
	 * @param multipartFile
	 * @return
	 * @author JobsZhang
	 * @date 2018年6月8日 下午5:48:17
	 */
	@RequestMapping(value="/uploadFile",method=RequestMethod.POST)
	@ResponseBody
	public BaseResDto uploadFile (@RequestParam("file") MultipartFile multipartFile){
		BaseResDto brd = new BaseResDto();
		FileInfo fileInfo = null;
		try {
			fileInfo = FileUploadUtil.uploadFile(multipartFile, request, uploadUrl, whitelist, false);
		} catch (IllegalStateException e) {
			brd.setMesg(e.getMessage());
		} catch (Exception e) {
			brd.setMesg(e.getMessage());
		}
		brd.setSuccess(true);
		brd.setValues(fileInfo);
		return brd;
	}
	
	
	@RequestMapping(value="/uploadFileWihthPath",method=RequestMethod.POST)
	@ResponseBody
	public BaseResDto uploadFileWihthPath (@RequestParam("file") MultipartFile multipartFile, @RequestParam("uploadPath") String uploadPath){
		BaseResDto brd = new BaseResDto();
		FileInfo fileInfo = null;
		try {
			fileInfo = FileUploadUtil.uploadFile(multipartFile, request, uploadUrl, whitelist, uploadPath,false);
		} catch (IllegalStateException e) {
			brd.setMesg(e.getMessage());
		} catch (Exception e) {
			brd.setMesg(e.getMessage());
		}
		brd.setSuccess(true);
		brd.setValues(fileInfo);
		return brd;
	}
	
	
	
	/**
	 * 
	 * <p>Title: checkFile</p>
	 * <p>Description:根据文件MD5查询文件是否存在 </p>
	 * @param fileMd5 文件唯一指纹
	 * @return
	 * @author JobsZhang
	 * @date 2018年6月8日 下午5:48:29
	 */
	@RequestMapping(value="/checkFile",method=RequestMethod.POST)
	@ResponseBody
	public BaseResDto checkFile (@RequestParam String fileMd5){
		BaseResDto brd = new BaseResDto();
		FileInfo fileInfo = fileInfoService.selectByMd5(fileMd5);
		brd.setSuccess(fileInfo!=null);
		brd.setValues(fileInfo);
		return brd;
	}
	
	/**
	 * 
	 * <p>Title: checkChunk</p>
	 * <p>Description: 检测分片是否已经存在</p>
	 * @param fileMd5 文件唯一指纹
	 * @param chunk 分片编号
	 * @param chunkSize 分片大小
	 * @return
	 * @author JobsZhang
	 * @date 2018年6月8日 下午5:48:56
	 */
	@RequestMapping(value="/checkChunk",method=RequestMethod.POST)
	@ResponseBody
	public BaseResDto checkChunk (@RequestParam String fileMd5,@RequestParam int chunk,@RequestParam long chunkSize){
		BaseResDto brd = new BaseResDto();
		String path = request.getSession().getServletContext().getRealPath(uploadUrl);
		String filePath = path+File.separator+fileMd5+File.separator+chunk;//合并文件必须要按照顺序合并，所以不能重命名		
		File file = new File(filePath);
		long length = file.length();
		if(file.exists()&&length==chunkSize){//分片已存在，这里一定要验证传过来的分片大小是否和已存在的分片大小相同，
			brd.setSuccess(true);
		}
		return brd;
	}
	
	/**
	 * 
	 * <p>Title: uploadChunks</p>
	 * <p>Description: 分片上传</p>
	 * @param fileMd5 文件唯一指纹
	 * @param chunk 分片编号
	 * @param chunkSize 分片大小
	 * @return
	 * @author JobsZhang
	 * @date 2018年6月8日 下午5:58:46
	 */
	@RequestMapping(value="/uploadChunks",method=RequestMethod.POST)
	@ResponseBody
	public BaseResDto uploadChunks (@RequestParam("file") MultipartFile multipartFile,ChunksReqDto reqDto){
		BaseResDto brd = new BaseResDto();
		FileInfo fileInfo = null;
		try {
			fileInfo = FileUploadUtil.chunksUpload(multipartFile, request, uploadUrl, whitelist, reqDto.getFileMd5(), reqDto.getChunk());
			brd.setSuccess(true);
			brd.setValues(fileInfo);
		} catch (IllegalStateException e) {
			e.printStackTrace();
			brd.setMesg("上传出错"+e.getMessage());
		}catch (Exception e) {
			e.printStackTrace();
			brd.setMesg("上传出错"+e.getMessage());
		}
		return brd;
	}
	/**
	 * 上传完成合并分片
	 * @param fileMd5 文件唯一指纹
	 * @param fileName 文件名
	 * @return
	 */
	@RequestMapping(value="/mergeChunks",method=RequestMethod.POST)
	@ResponseBody
	public BaseResDto mergeChunks (@RequestParam String fileMd5,@RequestParam String fileName){
		BaseResDto brd = new BaseResDto();
		FileInfo fileInfo = null;
		try {
			fileInfo = FileUploadUtil.mergeChunks(request, uploadUrl, whitelist, fileMd5, fileName, false);
			fileInfoService.insert(fileInfo);
			brd.setSuccess(true);
			brd.setValues(fileInfo);
		}catch (IllegalStateException e) {
			e.printStackTrace();
			brd.setMesg("合并文件出错"+e.getMessage());
		}catch (Exception e) {
			e.printStackTrace();
			brd.setMesg("合并文件出错"+e.getMessage());
		}
		return brd;
	}
	private boolean isMSBrowser(HttpServletRequest request) {
		String[] IEBrowserSignals = { "MSIE", "Trident", "Edge" };
		String userAgent = request.getHeader("User-Agent");
		for (String signal : IEBrowserSignals) {
			if (userAgent.contains(signal))
				return true;
		}
		return false;
	}




	public void downloadFile(String downLoadName,String filePath){
        File downloarFile = new File(filePath);
        if(downloarFile.exists()){
            downloadFile(downLoadName,downloarFile);
        }

    }
	  private void downloadFile(String downLoadName,File downloarFile){
	        response.setContentType("application/octet-stream");
	        boolean isMSIE = isMSBrowser(request);
	        if (isMSIE) {
	            //IE浏览器的乱码问题解决
	            try {
	                downLoadName = URLEncoder.encode(downLoadName, "UTF-8");
	            } catch (UnsupportedEncodingException e) {
	                logger.debug("DJ",e);
	            }
	        } else {
	            //万能乱码问题解决
	            try {
	                downLoadName = new String(downLoadName.getBytes("UTF-8"), "ISO-8859-1");
	            } catch (UnsupportedEncodingException e) {
	                logger.debug("DJ",e);
	            }
	        }

	        InputStream inStream = null;
	        response.reset();
	        response.setContentType("APPLICATION/OCTET-STREAM");
	        response.setHeader("Content-Disposition", "attachment;filename="+ downLoadName);
	        byte[] b = new byte[4096];
	        try {
	            inStream = new FileInputStream(downloarFile);
	            int len;
	            while ((len = inStream.read(b)) > 0)
	                response.getOutputStream().write(b, 0, len);

	        } catch (IOException e) {
	            logger.debug("DJ",e);
	        } finally {
	            if (inStream != null) {
	                try {
	                    inStream.close();
	                } catch (IOException e) {
	                    logger.debug("DJ",e);
	                }
	            }
	        }
	    }
	  
	  
	  @RequestMapping(value="/downloadFile")
		public void downloadTask(HttpServletResponse response,@RequestParam("filePath") String filePath ){
		  File file = new File(filePath);
		  if(!file.exists()){
			  response.setContentType("UTF-8");
	          response.setContentType("text/html;charset=UTF-8");
			  try {
				response.getWriter().write("文件不存在，请联系管理员");
				  response.getWriter().flush();
			} catch (IOException e) {
				e.printStackTrace();
			}
		  }else{
			  String fileName = file.getName();
		        if (file.exists()) {
		        	downloadFile(fileName,filePath);
		        } else {
		            response.setContentType("UTF-8");
		            response.setContentType("text/html;charset=UTF-8");
		            try {
		                response.getWriter().write("文件不存在，请联系管理员");
		                response.getWriter().flush();
		            } catch (IOException e) {
		                logger.debug("DJ",e);
		            }
		        }
		  }
		  
			
		}
}
